package cate.game.role.res.call;

import cate.common.table.call.row.CallDupWeightRow;
import cate.common.table.call.row.CallBaseRow;
import cate.common.table.call.row.CallCheatRow;
import cate.common.table.call.row.CallSpecialCheatRow;
import cate.common.table.call.row.CallWeightRow;
import cate.common.table.d.*;
import cate.common.table.item.hero.StarGroupList;
import cate.common.table.item.hero.row.HeroBaseRow;
import cate.common.util.GameResult;
import cate.common.util.XT;
import cate.common.util.random.RWList;
import cate.game.activity.wishblessing.RoleWishBlessing;
import cate.game.chat.ChatContentParam;
import cate.game.res.MixRes;
import cate.game.res.MixResItem;
import cate.game.res.RewardShow;
import cate.game.role.Role;
import cate.game.role.bag.BagContainer;
import cate.game.role.bag.hero.Hero;
import cate.game.role.res.call.base.CallProcessData;
import cate.game.role.res.call.base.CallResult;
import cate.game.role.res.call.msg.CallExeResp;
import cate.game.role.res.call.base.CallHeroResultItem;
import cate.game.train.hero.TrainHeroHandler;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

public class CallTool {


//    public  GameResult checkVip(Role role, CallBaseRow base) {
//        GameResult result = new GameResult<>();
//        if (role.getBase().vip < base.vipLimit) {
//            role.getGame().notice.message(role, 310202, "vip等级不足");
//            return result.fail("vip等级不足");
//        }
//        return result.success();
//    }

  public boolean checkVip(Role role, CallBaseRow base) {
    if (role.getBase().vip < base.vipLimit) {
      role.getGame().notice.message(role, 310202, "vip等级不足");
      return false;
    }
    return true;
  }

  /**
   * 可以随背包容量变化的检查
   *
   * @param role
   * @param bag
   * @param processData
   * @return
   */
  public boolean checkBag(Role role, BagContainer bag, CallProcessData processData) {
    if (processData.getMaxTime() == GD.INT_0) {
      return false;
    }
    processData.setMaxTime(Math.min(processData.getMaxTime(), bag.gridEmpty()));
    return true;
  }

  public boolean checkBag(Role role, BagContainer bag, CallBaseRow base) {
    if (base.callMode == GDHeroCall.Mode.NATURE) {
      return true;
    }
    if (bag.gridEmpty() < base.callTimes) {
      role.getGame().notice.message(role, 310201, "背包空间不足，请再腾出{s0}个格子再来召唤吧", base.callTimes - role.getBag().hero.gridEmpty());
      return false;
    }
    return true;
  }
//有道具 检测道具>背包 抽背包的数目
  //无道具 检测资源 数量> 背包 背包

  //走马灯

  /**
   * 走马灯通知
   *
   * @param role
   * @param processData
   */
  public void lampOnline(Role role, CallProcessData processData) {
    for (CallResult resultItem : processData.result) {
      if (resultItem.notice) {
        lampOnlineSingle(role, resultItem, processData);
      }
    }
  }

  protected void lampOnlineSingle(Role role, CallResult result, CallProcessData processData) {
    heroNoticeLamp(role, result.id, result.dup, GDHeroCall.Mode.getDesc(processData.base.callMode));
  }

  public void heroNoticeLamp(Role role, int id, boolean dup, String modeDesc) {
    CallWeightRow itemRow = role.getGame().table.call.weight.get(id);

    List<ChatContentParam> params = new ArrayList<>();
    params.add(ChatContentParam.c(ChatContentParam.TYPE_STRING, role.getBase().name));
//        params.add(ChatContentParam.c(ChatContentParam.TYPE_STRING, modeDesc));
//        params.add(ChatContentParam.c(ChatContentParam.TYPE_STRING, heroGrade(itemRow.heroId, role)));
    params.add(ChatContentParam.c(ChatContentParam.TYPE_HERO_ID, itemRow.heroId));
    if (dup) {

    } else {
      role.getGame().notice.lampOnline(role, GDNotice.TextId.HERO_STAR_FIVE, params);
    }
  }

  public void FragNoticeLamp(Role role, CallProcessData processData) {
    for (CallResult resultItem : processData.result) {
      if (resultItem.notice) {
        CallWeightRow itemRow = role.getGame().table.call.weight.get(resultItem.id);
        List<ChatContentParam> params = new ArrayList<>();
        params.add(ChatContentParam.c(ChatContentParam.TYPE_STRING, role.getBase().name));
        params.add(ChatContentParam.c(ChatContentParam.TYPE_HERO_PART_ID, MixResItem.parse(itemRow.fragmentStr)));
        role.getGame().notice.lampOnline(role, GDNotice.TextId.NATURE_STAR_FIVE, params);
      }
    }
  }

//检查函数

  /**
   * 检查消耗碎钻
   *
   * @param role
   * @param processData
   * @return
   */
  public boolean checkCostM1(Role role, CallProcessData processData) {
    if (StringUtils.isNotBlank(processData.base.costM1Str)) {
      MixRes consume = new MixRes((processData.base.costM1Str));
      GameResult<MixResItem> r = consume.consumeCheck(role, null);
      if (r.ok()) {
        role.getGame().notice.tipResItem(role, r.data);
        processData.cost.addList(consume);
        return true;
      }
    }
    return false;
  }


  /**
   * 碎钻抽送经验
   *
   * @param role
   * @param processData
   */
  public void costM1(Role role, CallProcessData processData) {
    processData.addReward(new MixRes(processData.base.rewardExpStr));
  }

  /**
   * 暴力抽取-检查消耗碎钻
   *
   * @param role
   * @param processData
   * @return
   */
  public boolean checkCostM1HaveMad(Role role, CallProcessData processData) {
    if (StringUtils.isBlank(processData.base.costM1Str)) {
      return false;
    }
    long count = role.getBag().numRes.count(GDObj.Num.M1);
    long unit = new MixRes(processData.base.costM1Str).count(GDObj.Type.NUM, GDObj.Num.M1);
    if (unit == 0L) {
      return false;
    }
    long num = count / unit;
    if (num == 0L) {
      return false;
    }
    if (processData.checkMad()) {
      processData.setMaxTime(Math.min((int) num, processData.base.callTimes));
      if (!checkBag(role, role.getBag().hero, processData)) {
        return false;
      }
      MixRes cost = new MixRes(processData.base.costM1Str);
      cost.multiply(processData.getMaxTime());
      processData.addCost(cost);
      return true;
    }
    MixRes consume = new MixRes((processData.base.costM1Str));
    GameResult<MixResItem> r = consume.consumeCheck(role, null);
    if (r.ok()) {
      processData.addCost(consume);
      return true;
    }
    return false;
  }


  /**
   * 暴力抽取-碎钻抽送经验
   *
   * @param role
   * @param processData
   */
  public void costM1HaveMad(Role role, CallProcessData processData) {
    MixRes reward = new MixRes(processData.base.rewardExpStr);
    if (processData.checkMad()) {
      reward.multiply(processData.getMaxTime());
    }
    processData.addReward(reward);
  }


  /**
   * 道具消耗检测
   *
   * @param role
   * @param processData
   * @return
   */
  public boolean checkProp(Role role, CallProcessData processData) {
    if (processData.base.costPropId == 0) {
      return false;
    }
    int count = (int) role.getBag().prop.count(processData.base.costPropId);
    MixResItem item = new MixResItem(GDObj.Type.PROP, processData.base.costPropId, processData.base.costPropNum);
    if (count >= processData.base.costPropNum) {
      processData.addCost(item);
      return true;
    }
    role.getGame().notice.tipResItem(role, item);
    return false;
  }


  /**
   * 暴力抽取-道具消耗检测
   *
   * @param role
   * @param processData
   * @return
   */
  public boolean checkCostHaveMad(Role role, CallProcessData processData) {
    int count = (int) role.getBag().prop.count(processData.base.costPropId);
    int useCount = 0;
    if (processData.checkMad()) {
      processData.setMaxTime(Math.min(count, processData.base.callTimes));
      //狂暴模式
      if (checkBag(role, role.getBag().hero, processData)) {
        MixResItem item = new MixResItem(GDObj.Type.PROP, processData.base.costPropId, processData.getMaxTime());
        processData.addCost(item);
        return true;
      }
    } else if (count >= processData.base.costPropNum) {
      MixResItem item = new MixResItem(GDObj.Type.PROP, processData.base.costPropId, processData.base.costPropNum);
      processData.addCost(item);
      return true;
    } else if (count > 0) {
      useCount = count;
      MixResItem item = new MixResItem(GDObj.Type.PROP, processData.base.costPropId, useCount);
      processData.addCost(item);
    } else if (StringUtils.isBlank(processData.base.costM1Str)) {
      return false;
    }
    //钻石
    long unit = new MixRes(processData.base.costM1Str).count(GDObj.Type.NUM, GDObj.Num.M1);
    if (unit == 0L) {
      return false;
    }
    long num;
    long countM1 = role.getBag().numRes.countM1();
    if (useCount > 0) {
      num = countM1 / ((processData.base.callTimes - useCount) * 220);
    } else {
      num = countM1 / unit;
    }
    if (num == 0L) {
      return false;
    }
    if (processData.checkMad()) {
      processData.setMaxTime(Math.min((int) num, processData.base.callTimes));
      if (!checkBag(role, role.getBag().hero, processData)) {
        return false;
      }
      MixRes cost = new MixRes(processData.base.costM1Str);
      cost.multiply(processData.getMaxTime());
      processData.addCost(cost);
      MixRes reward = new MixRes(processData.base.rewardExpStr);
      reward.multiply(processData.getMaxTime());
      processData.addReward(reward);
      return true;
    }
    MixRes consume = new MixRes();
    if (useCount > 0) {
      consume.addItem(new MixResItem(GDObj.Type.NUM, GDObj.Num.M1, (processData.base.callTimes - useCount) * 220));
    } else {
      consume.addList(new MixRes(processData.base.costM1Str));
    }
    GameResult<MixResItem> r = consume.consumeCheck(role, null);
    if (r.ok()) {
      processData.addCost(consume);
      MixRes reward = new MixRes(processData.base.rewardExpStr).multiply(processData.base.callTimes - useCount);
      processData.addReward(reward);
      return true;
    }
    return false;
  }

  /**
   * 友情点检测与消耗
   *
   * @param role
   * @param processData
   * @return
   */
  public boolean checkFriendPoint(Role role, CallProcessData processData) {
    if (StringUtils.isNotBlank(processData.base.costFriendStr)) {
      MixRes cost = new MixRes(processData.base.costFriendStr);
      if (cost.consumeCheck(role, null).ok()) {
        processData.addCost(cost);
        return true;
      }
    }
    return false;
  }


  /**
   * 无该项检测 继承后返回false 即可
   *
   * @param role
   * @param processData
   * @return boolean
   */
  public boolean checkScore(Role role, CallProcessData processData) {
    final CallPO callPO = role.getRes().callPO;
    if (processData.base.costScoreNum == GD.INT_0) {
      return false;
    }
    if (callPO.score.checkEnough(processData.base.costScoreNum)) {
      return true;
    }
    return false;
  }

  public void costScore(Role role, CallProcessData processData) {
    final CallPO callPO = role.getRes().callPO;
    callPO.score.addScore(-processData.base.costScoreNum);
  }


  /**
   * 免费次数检查
   *
   * @param processData
   * @param basePO
   * @return
   */
  public boolean checkFree(CallProcessData processData, CallBasePO basePO) {
    if (basePO.baseData.freeTimes > 0 && processData.base.freeMax > 0) {
      return true;
    }

    long curTime = System.currentTimeMillis();
    if (processData.base.refreshInterval == GD.INT_0) {
      return false;
    }

    basePO.baseData.freeTimes = Math.min(processData.base.freeMax,
            (int) ((curTime - basePO.baseData.lastFreeTime) / (processData.base.refreshInterval * 1000)));

    if (basePO.baseData.freeTimes > 0) {
      return true;
    }

    return false;
  }

  public void costFreeReset(CallBasePO basePO) {
    basePO.baseData.freeTimes--;
    basePO.baseData.lastFreeTime = System.currentTimeMillis();
  }


  //抽取函数
  public CallWeightRow doGeneralCall(Role role, Collection<CallWeightRow> list) {
    if (list == null) {
      return null;
    }
    RWList<CallWeightRow> rwList = new RWList<>();
    rwList.addAndSetup(list);
    CallWeightRow row;
    row = rwList.get();
    return row;
  }

  public CallWeightRow doGeneralCall(Role role, int groupId) {
    Map<Integer, CallWeightRow> list = role.getGame().table.call.weight.groupMap.get(groupId);
    if (list == null) {
      role.getGame().notice.message(role, "配置错误");
      return null;
    }
    RWList<CallWeightRow> rwList = new RWList<>();
    rwList.addAndSetup(list.values());
    CallWeightRow row;
    row = rwList.get();
    return row;
  }

  public CallWeightRow doGeneralCallWithActivity(Role role, int groupId) {
    Map<Integer, CallWeightRow> list = role.getGame().table.call.weight.groupMap.get(groupId);
    if (list == null) {
      role.getGame().notice.message(role, "配置错误");
      return null;
    }
    RWList<CallWeightRow> rwList = new RWList<>();

    RoleWishBlessing blessing = role.getActivity().getEnableActivitySingle(GDFunc.WISH_BLESSING);
    if (blessing != null) {
      List<String> exclude = blessing.banRewardList();
      rwList.addAndSetup(list.values().stream().filter(e -> !exclude.contains(e.fragmentStr)).collect(Collectors.toList()));
    } else {
      rwList.addAndSetup(list.values());
    }
    CallWeightRow row;
    row = rwList.get();
    return row;
  }

  //机制

  /**
   * 积分召唤 普通，高级，友情召唤均加积分
   */
  public void addAllScore(Role role, CallProcessData processData) {
    role.getRes().callPO.score.addScore(processData.allRewardScore());
  }


  @NoteField(value = "十连保有四星")
  public static final int ENSURE_ONE_FOUR_STAR_HERO_TIMES = 10;

  @NoteField(value = "四星保底机制的抽食灵池")
  public static final int ENSURE_ONE_FOUR_STAR_GROUP_ID = 4;

  /**
   * 十连保四星
   *
   * @param role
   * @param processData
   */
  public void ensureOneFourStarHero(Role role, CallProcessData processData) {
    if (processData.base.callTimes == ENSURE_ONE_FOUR_STAR_HERO_TIMES) {
      List<CallResult> result = processData.result;
      int low = (int) result.stream()
              .map(item -> role.getGame().table.hero.base.get(role.getGame().table.call.weight.get(item.id).heroId).star)
              .filter(i -> i < 4).count();

      if (low == result.size()) {
        CallWeightRow row = doGeneralCall(role, ENSURE_ONE_FOUR_STAR_GROUP_ID);
        CallResult resultItem = result.get(low - 1);
        replaceResultByPriority(resultItem, row.id, GDHeroCall.CallPriority.ENSURE_ONE_FOUR_STAR_HERO);
      }
    }
  }

  /**
   * 不同机制根据优先级决定替换还是不替换
   *
   * @param resultItem
   * @param id
   * @param modPriority
   */
  public boolean replaceResultByPriority(CallResult resultItem, int id, int modPriority) {
    if (resultItem.priority <= modPriority) {
      resultItem.id = id;
      resultItem.priority = modPriority;
      return true;
    }
    return false;
  }

  /**
   * 按照配置给定次数的抽取走特定池
   *
   * @param role
   * @param processData
   * @param basePO
   */
  public void forceAppointPoolReCall(Role role, CallProcessData processData, CallBasePO basePO) {
    int lateNeedCommonReplaceNum = 0;
    StarGroupList.Item item = null;
    for (CallResult resultItem : processData.result) {
      if (lateNeedCommonReplaceNum > 0) {
        CallWeightRow row = doGeneralCall(role, basePO.onGetPool(item.groupId));
        replaceResultByPriority(resultItem, row.id, GDHeroCall.CallPriority.FORCE_APPOINT_POOL_RECALL);
        lateNeedCommonReplaceNum--;
        continue;
      }

      CallSpecialCheatRow specialCheatRow = role.getGame().table.call
              .specialCheat.getRow(processData.base.callMode, resultItem.getIndex() + basePO.baseData.totalTimes);
      if (specialCheatRow == null) {
        continue;
      }
      lateNeedCommonReplaceNum = specialCheatRow.endTime - (resultItem.getIndex() + basePO.baseData.totalTimes);

      item = specialCheatRow.config.get();

      CallWeightRow row = doGeneralCall(role, basePO.onGetPool(item.groupId));
      replaceResultByPriority(resultItem, row.id, GDHeroCall.CallPriority.FORCE_APPOINT_POOL_RECALL);
    }
  }


  /**
   * 双黄蛋机制，只有召唤结果为英雄的召唤可能存在
   */
  public void randomDup(Role role, CallProcessData processData) {
    if (!processData.base.duplicate) {
      return;
    }
    for (CallResult resultItem : processData.result) {
      CallWeightRow row = role.getGame().table.call.weight.get(resultItem.id);

      CallDupWeightRow rateRow = role.getGame().table.call.dupWeight.getByHeroId(row.heroId);
      if (rateRow == null) {
        return;
      }
      int point = XT.randomRange(1, 10000);
      if (point < rateRow.weight) {
        resultItem.dup = true;
      }
    }
  }


  /**
   * 【】抽不中五星,保进【】分组（走策划配表）只有英雄可用
   *
   * @param role
   * @param processData
   * @param basePO
   */
  public void ensureFiveHeroPool(Role role, CallProcessData processData, CallBasePO basePO) {
    CallCheatRow cheatCall = role.getGame().table.call.cheat.getRow(processData.base.callMode);
    if (cheatCall == null) {
      return;
    }

    List<CallResult> list = processData.result.stream()
            .sorted(Comparator.comparing(CallResult::getIndex))
            .collect(Collectors.toList());
    int unFiveStarTimes = basePO.baseData.uNFiveStarTimes;

    for (CallResult result : list) {
      if (role.getGame().table.hero.base.get(result.getRow(role).heroId).star == 5) {
        unFiveStarTimes = 0;
        continue;
      }
      unFiveStarTimes++;
      if (unFiveStarTimes < cheatCall.times) {
        continue;
      }
      unFiveStarTimes = 0;
      CallWeightRow row = basePO.tool.doGeneralCall(role, cheatCall.group);
      basePO.tool.replaceResultByPriority(result, row.id, GDHeroCall.CallPriority.ENSURE_FIVE_HERO_POOL);
    }

  }

  /**
   * 限制五星英雄个数
   *
   * @param role
   * @param processData
   * @param basePO
   */
  public void limitStarFiveHeroNum(Role role, CallProcessData processData, CallBasePO basePO) {
    if ((!processData.base.defendMark)) {
      return;
    }
    int upperBound = processData.getMaxTime() / GDHeroCall.CALL_TEN_TIMES;
    upperBound *= processData.base.limitFive;
    int num = (int) processData.result.stream()
            .filter(result -> role.getGame().table.hero.base.get(result.getRow(role).heroId).star == GDHeroCall.Star.Five)
            .count();
    if (num < upperBound) {
      return;
    }
    int needReplaceNum = num - upperBound;
    for (CallResult result : processData.result) {
      if (role.getGame().table.hero.base.get(result.getRow(role).heroId).star < GDHeroCall.Star.Five) {
        continue;
      }
      if (needReplaceNum <= 0) {
        break;
      }
      CallWeightRow row = doGeneralCall(role, processData.base.replaceGroup);
      if (replaceResultByPriority(result, row.id, GDHeroCall.CallPriority.LIMIT_STAR_FIVE_HERO_NUM)) {
        needReplaceNum--;
      }
    }
  }

  public void resultAddNotice(Role role, CallProcessData processData) {
    for (CallResult resultItem : processData.result) {
      CallWeightRow row = role.getGame().table.call.weight.get(resultItem.id);
      resultItem.notice = row.notice;
    }
  }

  /**
   * 构造消息 碎片类型
   *
   * @param role
   * @param processData
   * @param po
   */
  public void sendFragCallResp(Role role, CallProcessData processData, CallBasePO po) {
    CallExeResp resp = new CallExeResp();
    resp.type = po.getMode();
    RoleWishBlessing act = role.getActivity().getEnableActivitySingle(GDFunc.WISH_BLESSING);
    MixRes actCostItem = processData.base.callType < GDHeroCall.Mode.NATURE_POINTS_EXCHANGE_START && act != null ? new MixRes(act.costItemStr()) : null;
    for (CallResult result : processData.result) {
      CallWeightRow row = result.getRow(role);
      resp.fragments.add(new MixRes(row.fragmentStr));
      resp.fragUidList.add(row.id);
      resp.reward.addList(new MixRes(row.rewardStr));
      resp.reward.addList(processData.reward);
      resp.reward.addList(processData.sentReward);

      if (actCostItem != null && StringUtils.isNotBlank(row.fragmentStr) &&  act.isLuckyItem(row.fragmentStr)) {
        GameResult<MixResItem> res = actCostItem.consume(role);
        if (res.ok()) {
          resp.actExtraReward.addList(act.calcActExtraReward(row.fragmentStr));
        }
      }
    }
    if (!resp.actExtraReward.isEmpty()) {
      resp.actExtraReward.add(role, true, GDOperation.WISH_BLESSING_LUCKY_REWARD);
    }

    resp.sendNow(role);
  }

  /**
   * 发送构造消息:英雄类型
   *
   * @param role
   * @param processData
   * @param po
   */
  public void sendHeroCallResp(Role role, CallProcessData processData, CallBasePO po) {
    CallExeResp resp = new CallExeResp();
    resp.type = po.getMode();
    for (CallResult result : processData.result) {
      CallWeightRow row = result.getRow(role);
      resp.result.add(new CallHeroResultItem(row.heroId, result.notice, result.dup));
      if (result.remove) {
        resp.sacrifices.add(new Hero(role, row.heroId));
      }
    }
    resp.reward.addList(processData.reward);
    resp.reward.addList(processData.sentReward);
    resp.sendNow(role);
  }

  /**
   * 英雄献祭
   *
   * @param role
   * @param processData
   * @return
   */
  public EcResult<RewardShow> sacrificeHero(Role role, CallProcessData processData) {
    EcResult<RewardShow> r = new EcResult<>();
    if (!role.getRes().callPO.autoResolve) {
      return r.success();
    }
    // 每个阵营三星保留8个
    Map<Byte, Integer> threeStarHeros = new HashMap<>();
    for (Hero hero : role.getBag().hero.getList()) {
      HeroBaseRow tpl = hero.getTpl(role.getGame());
      if (tpl.star == 3) {
        threeStarHeros.put(tpl.camp, threeStarHeros.getOrDefault(tpl.camp, 0) + 1);
      }
    }
    List<Hero> sacrifices = new LinkedList<>();
    for (CallResult result : processData.result) {
      CallWeightRow row = result.getRow(role);
      HeroBaseRow tpl = role.getGame().table.hero.base.get(row.heroId);
      if (tpl.star < 4) {
        if (tpl.star < 3 || threeStarHeros.getOrDefault(tpl.camp, 0) >= 8) {
          result.remove = true;
          sacrifices.add(new Hero(role, tpl.id));
        } else if (tpl.star == 3){
          threeStarHeros.put(tpl.camp, threeStarHeros.getOrDefault(tpl.camp, 0) + 1);
        }
      }
    }

    if (!sacrifices.isEmpty()) {
      r = TrainHeroHandler.calReturn(role, sacrifices, TrainHeroHandler.sacrificeOpt());
      role.getHistory().action.heroSacrifice(sacrifices.size());
      sacrifices.forEach(e -> role.getRes().heroIntroduction.addHero(e.tid, e.getTpl(role.getGame()).protoId));
    }

    if (r.ok() && r.data != null) {
      processData.sentReward.addList(r.data.tplRwd);
    }
    return null;
  }

  /**
   * 给玩家发奖励 （英雄）
   *
   * @param role
   * @param processData
   */
  public void sendResultToRole(Role role, CallProcessData processData) {
    List<Hero> heros = new LinkedList<>();
    for (CallResult result : processData.result) {
      if (result.remove) {
        continue;
      }
      heros.add(new Hero(role, result.getRow(role).heroId));
      if (result.dup) {
        heros.add(new Hero(role, result.getRow(role).heroId));
      }
    }

    if (CollectionUtils.isEmpty(heros)) {
      return;
    }

//        log.info("玩家{}抽到的食灵为:{}", role.getBase().name, heros.stream().map(e -> String.valueOf(e.tid)).collect(Collectors.joining(",")));
    if (heros.size() > role.getBag().hero.calcCapacity() - role.getBag().hero.getList().size()) {
      MixRes item = new MixRes();
      heros.forEach(e -> item.addItem(new MixResItem(e)));
      item.addList(processData.reward);
      item.add(role, true, GDOperation.HERO_CALL_EXE);
      return;
    }

    processData.reward.add(role);
    role.getBag().hero.addItems(heros, null);
  }

  /**
   * 更新各种召唤数值(有英雄)，以及记录任务
   *
   * @param role
   * @param processData
   * @param po
   */
  public void updatePo(Role role, CallProcessData processData, CallBasePO po) {
    if (po.getMode() == GDHeroCall.Mode.NATURE) {
      if (processData.base.callType <= GDHeroCall.Mode.NATURE_POINTS_EXCHANGE_START) {
        po.baseData.totalTimes += processData.getMaxTime();
        role.getHistory().action.heroCall(processData.base.callMode, processData.consumedTimes);
        role.getHistory().action.heroGodCall(processData.consumedTimes);
        for (int i = 0; i < processData.consumedTimes; i ++){
          role.getRes().hoard.addition.addTask(GDHoardTask.WISH);
        }
      } else if (processData.base.callType <= GDHeroCall.Mode.NATURE_POINTS_EXCHANGE_END) {
        role.getHistory().action.heroGodScoreCall(processData.consumedTimes);
      }
      role.getHistory().action.heroGodAll(processData.consumedTimes);
      return;
    }

    po.baseData.totalTimes += processData.getMaxTime();
    role.getHistory().action.heroCall(processData.base.callMode, processData.consumedTimes);
    int fiveStarPoint = processData.result.stream()
            .filter(result -> role.getGame().table.hero.base.get(result.getRow(role).heroId).star == 5)
            .mapToInt(item -> item.getIndex())
            .max()
            .orElse(0);
    if (fiveStarPoint == 0) {
      po.baseData.uNFiveStarTimes += processData.getMaxTime();
      return;
    }
    po.baseData.uNFiveStarTimes = processData.getMaxTime() - fiveStarPoint;
  }

  /**
   * 根据type获取召唤配置
   *
   * @param role
   * @param type
   * @return
   */
  public CallBaseRow getBaseRow(Role role, int type) {
    CallBaseRow row = role.getGame().table.call.base.get(type);
    if (row == null) {
      role.getGame().notice.message(role, "错误的召唤类型");
      return null;
    }
    return row;
  }
}
